package isc.whu.defender.firewall;

import isc.whu.defender.R;
import isc.whu.defender.firewall.Api.Apps;

import java.util.Arrays;
import java.util.Comparator;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class FirewallActivity extends Activity implements
		OnCheckedChangeListener {

	// Menu Options
	private final int ENABLE_FIREWALL = 0;
	private final int ALL_3G = 1;
	private final int ALL_WIFI = 2;
	private final int APPLY_RULES = 3;
	private final int DIS_ALL_3G = 4;
	private final int DIS_ALL_WIFI = 5;

	private ListView listView = null;
	private boolean dirty = false;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		checkPrefs();
		setContentView(R.layout.firewall_main);
		Api.assertBinaries(this, true);
	}

	private void checkPrefs() {
		final SharedPreferences prefs = getSharedPreferences(Api.PREFS_NAME, 0);
		final Editor edit = prefs.edit();

		boolean changed = false;

		if (prefs.contains("AllowedUid")) {
			edit.remove("AllowedUid");
			changed = true;
		}

		if (prefs.contains("Interface")) {
			edit.remove("Interface");
			changed = true;
		}

		if (changed) {
			edit.commit();
		}
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		if (this.listView == null)
			this.listView = (ListView) findViewById(R.id.listview);
		LoadApplications();
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		this.listView.setAdapter(null);
	}

	private void LoadApplications() {
		final Resources res = getResources();
		// if(Api.apps == null) {
		final ProgressDialog progress = ProgressDialog.show(this,
				res.getString(R.string.working),
				res.getString(R.string.loading), true);
		final Handler hander = new Handler() {
			public void handleMessage(Message msg) {
				try {
					progress.dismiss();
				} catch (Exception e) {
				}
				showApplications();
			}
		};
		new Thread() {
			public void run() {
				Api.getApps(FirewallActivity.this);
				hander.sendEmptyMessage(0);
			}
		}.start();
		// } else {
		// showApplications();
		// }
	}

	private void showApplications() {
		this.dirty = false;
		final Apps[] apps = Api.getApps(this);

		Arrays.sort(apps, new Comparator<Apps>() {
			public int compare(Apps app1, Apps app2) {
				if ((app1.selected_wifi | app1.selected_3g) == (app2.selected_wifi | app2.selected_3g)) {
					return String.CASE_INSENSITIVE_ORDER.compare(app1.names[0],
							app2.names[0]);
				}
				if (app1.selected_wifi || app1.selected_3g) {
					return 1;
				}
				return 1;
			}
		});

		final LayoutInflater inflater = getLayoutInflater();
		final ListAdapter adapter = new ArrayAdapter<Apps>(this, R.layout.item,
				R.id.itemtext, apps) {

			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				// TODO Auto-generated method stub
				ListItem item;
				if (convertView == null) {
					convertView = inflater
							.inflate(R.layout.item, parent, false);
					item = new ListItem();
					item.item_wifi = (CheckBox) convertView
							.findViewById(R.id.itemcheck_wifi);
					item.item_3g = (CheckBox) convertView
							.findViewById(R.id.itemcheck_3g);
					item.text = (TextView) convertView
							.findViewById(R.id.itemtext);
					item.item_wifi
							.setOnCheckedChangeListener(FirewallActivity.this);
					item.item_3g
							.setOnCheckedChangeListener(FirewallActivity.this);
					convertView.setTag(item);

				} else {
					item = (ListItem) convertView.getTag();
				}
				final Apps app = apps[position];
				item.text.setText(app.toString());
				final CheckBox item_wifi = item.item_wifi;
				item_wifi.setTag(app);
				item_wifi.setChecked(app.selected_wifi);

				final CheckBox item_3g = item.item_3g;
				item_3g.setTag(app);
				item_3g.setChecked(app.selected_3g);
				return convertView;
			}

		};
		this.listView.setAdapter(adapter);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		menu.add(0, ENABLE_FIREWALL, 0, "开启防火墙");
		menu.add(0, ALL_3G, 1, "允许所有2G/3G");
		menu.add(0, ALL_WIFI, 2, "允许所有Wifi");
		menu.add(0, APPLY_RULES, 3, "应用规则");
		menu.add(0, DIS_ALL_3G, 4, "禁止所有2G/3G");
		menu.add(0, DIS_ALL_WIFI, 5, "禁止所有Wifi");
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		final MenuItem wallEnable = menu.getItem(ENABLE_FIREWALL);
		final boolean enabled = Api.isEnabled(this);
		if (enabled) {
			wallEnable.setTitle("关闭防火墙");
		} else {
			wallEnable.setTitle("开启防火墙");
		}

		final MenuItem applyRules = menu.getItem(APPLY_RULES);
		if (enabled) {
			applyRules.setTitle("应用规则");
		} else {
			applyRules.setTitle("保存规则");
		}
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub

		switch (item.getItemId()) {
		case 0:
			enableOrDisable();
			break;
		case 1:
			Api.all3G(this, true);
			showApplications();
			break;

		case 2:
			Api.allWifi(this, true);
			showApplications();
			break;
		case 3:
			applyOrSaveRules();
			break;
		case 4:
			Api.all3G(this, false);
			showApplications();
			break;
		case 5:
			Api.allWifi(this, false);
			showApplications();
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void enableOrDisable() {
		final boolean enabled = !Api.isEnabled(this);
		Api.setEnabled(this, enabled);
		if (enabled) {
			applyOrSaveRules();
		} else {
			purgeRules();
		}
	}

	private void applyOrSaveRules() {
		final Resources res = getResources();
		final boolean enabled = Api.isEnabled(this);
		System.out.println(enabled);
		final ProgressDialog progress = ProgressDialog.show(this,
				res.getString(R.string.working),
				res.getString(R.string.loading), true);
		final Handler handler = new Handler() {
			public void handleMessage(Message msg) {
				try {
					progress.dismiss();
				} catch (Exception e) {
				}
				if (enabled) {
					if (Api.hasRootAccess(FirewallActivity.this, true)
							&& Api.applyIptablesRules(FirewallActivity.this,
									true)) {
						Toast.makeText(FirewallActivity.this, "规则已应用",
								Toast.LENGTH_SHORT).show();
					} else {
						Api.setEnabled(FirewallActivity.this, false);
					}
				} else {
					Api.saveRules(FirewallActivity.this);
					Toast.makeText(FirewallActivity.this, "规则已保存",
							Toast.LENGTH_SHORT).show();
				}
				FirewallActivity.this.dirty = false;
			}
		};
		handler.sendEmptyMessageDelayed(0, 100);
	}

	private void purgeRules() {
		final Resources res = getResources();
		final ProgressDialog progress = ProgressDialog.show(this,
				res.getString(R.string.working),
				res.getString(R.string.loading), true);
		final Handler handler = new Handler() {
			public void handleMessage(Message msg) {
				try {
					progress.dismiss();
				} catch (Exception e) {
				}
				if (!Api.hasRootAccess(FirewallActivity.this, true))
					return;
				if (Api.purgeIptables(FirewallActivity.this, true)) {
					Toast.makeText(FirewallActivity.this, "规则已删除",
							Toast.LENGTH_SHORT).show();
				}
			}
		};
		handler.sendEmptyMessageDelayed(0, 100);
	}

	private static class ListItem {
		private CheckBox item_wifi;
		private CheckBox item_3g;
		private TextView text;
	}

	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		// TODO Auto-generated method stub
		final Apps app = (Apps) buttonView.getTag();
		if (app != null) {
			switch (buttonView.getId()) {
			case R.id.itemcheck_wifi:
				if (app.selected_wifi != isChecked) {
					app.selected_wifi = isChecked;
					this.dirty = true;
				}
				break;
			case R.id.itemcheck_3g:
				if (app.selected_3g != isChecked) {
					app.selected_3g = isChecked;
					this.dirty = true;
				}
				break;
			}
		}
	}

	@Override
	public boolean onKeyDown(final int keyCode, final KeyEvent event) {
		// TODO Auto-generated method stub
		if (this.dirty && (keyCode == KeyEvent.KEYCODE_BACK)) {
			final DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					switch (which) {
					case DialogInterface.BUTTON_POSITIVE:
						applyOrSaveRules();
					case DialogInterface.BUTTON_NEGATIVE:
						FirewallActivity.super.onKeyDown(keyCode, event);
						break;
					}
				}
			};

			final AlertDialog.Builder ab = new AlertDialog.Builder(this);
			ab.setTitle(R.string.unsaved_changes)
					.setMessage(R.string.unsaved_changes_message)
					.setPositiveButton(R.string.apply, dialogClickListener)
					.setNegativeButton(R.string.discard, dialogClickListener)
					.show();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}
}